using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEditor.MPE;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UIElements;

namespace SunshineFarmWord
{
    public class PlayerBaseStates : IState
    {
        protected PlayerStateMachine stateMachine;

        // 玩家运动数据
        protected PlayerRunData movementData;

        protected PlayerStatesData playerStatesData;

        //碰撞进入事件
        private Dictionary<string, Action<Collider2D>> _onTriggerActionsEnter2DCallbacks = new Dictionary<string, Action<Collider2D>>();

        //碰撞退出事件
        private Dictionary<string, Action<Collider2D>> _onTriggerActionsExit2DCallbacks = new Dictionary<string, Action<Collider2D>>();

        //碰撞中触发事件
        private Dictionary<string, Action<Collider2D>> _onTriggerActionsTriggerStay2DCallbacks = new Dictionary<string, Action<Collider2D>>();

        //物理事件碰撞处理
        private Dictionary<string, Action<Collision2D>> _onCollision2DEnterActionsCallbacks = new Dictionary<string, Action<Collision2D>>();
        private Dictionary<string, Action<Collision2D>> _onCollision2DExitActionsCallbacks = new Dictionary<string, Action<Collision2D>>();

        public PlayerBaseStates(PlayerStateMachine playerStateMachine)
        {
            stateMachine = playerStateMachine;

            //初始化数据
            movementData = stateMachine.Player.Data.RunData;
            playerStatesData = stateMachine.Player.Data.PlayerStatesData;

            if (stateMachine.ReusableData.PlayerStatesData == null)
            {
                stateMachine.ReusableData.PlayerStatesData = new PlayerStatesData();
            }


            //初始化碰撞回调
            AddCollider2DEnterActions();
            AddTriggerCollider2DStayActions();
            AddCollider2DExitActions();
            //物理碰撞 包含物理数据
            AddCollision2DEnterActions();
            AddCollision2DExitActions();
        }

        #region 继承IState接口
        public virtual void Enter()
        {
            Debug.Log("当前状态为------>" + GetType().Name);

            //添加输入回调
            AddInputActionsCallbacks();
        }

        public virtual void Exit()
        {
            //移除输入回调
            RemoveInputActionsCallbacks();
        }

        public virtual void HandleInput()
        {
            ReadMovementInput();
        }

        public virtual void OnAnimationEnterEvent()
        {
            //
        }

        public virtual void OnAnimationExitEvent()
        {
            //
        }

        public virtual void OnAnimationTransitionEvent()
        {
            //
        }

        public virtual void OnTriggerEnter2D(Collider2D collider)
        {
            //
            if (_onTriggerActionsEnter2DCallbacks.TryGetValue(collider.tag, out Action<Collider2D> callback))
            {
                callback(collider);
            }
        }

        public virtual void OnTriggerExit2D(Collider2D collider)
        {
            if (_onTriggerActionsExit2DCallbacks.TryGetValue(collider.tag, out Action<Collider2D> callback))
            {
                callback(collider);
            }
        }

        // 处理物理碰撞，涉及物理作用力
        public virtual void OnCollisionEnter2D(Collision2D collision)
        {
            if (_onCollision2DEnterActionsCallbacks.TryGetValue(collision.gameObject.tag, out Action<Collision2D> callback))
            {
                callback(collision);
            }
        }

        public virtual void OnCollisionExit2D(Collision2D collision)
        {
            if (_onCollision2DExitActionsCallbacks.TryGetValue(collision.gameObject.tag, out Action<Collision2D> callback))
            {
                callback(collision);
            }
        }

        //碰撞中
        public virtual void OnTriggerStay2D(Collider2D collider)
        {
            if (_onTriggerActionsTriggerStay2DCallbacks.TryGetValue(collider.gameObject.tag, out Action<Collider2D> callback))
            {
                callback(collider);
            }
        }

        public virtual void PhysicsUpdate()
        {
            //
        }

        public virtual void Update()
        {
            //
        }
        #endregion

        #region Main function

        // 移动
        protected virtual void Move()
        {
            // 玩家没有输入
            // 或者基础速度 为0
            if (stateMachine.ReusableData.MovementInput == Vector2.zero || stateMachine.ReusableData.MovementSpeedModifier == 0f) return;

            float speed = GetMovementSpeed();

            // 玩家旋转
            PlayerRotate();

            stateMachine.Player.transform.Translate(stateMachine.ReusableData.MovementInput * speed * Time.deltaTime);
        }

        //玩家旋转方向
        private void PlayerRotate()
        {
            // 玩家朝向
            PlayerSO.PlayerFaceEnum faceDirection = GetFaceDirection(stateMachine.ReusableData.MovementInput);

            // 玩家朝向与输入方向不同
            if (faceDirection != stateMachine.ReusableData.playerFaceEnum)
            {
                stateMachine.Player.SetPlayerFace(faceDirection);
            }
        }

        // 读取移动输入
        private void ReadMovementInput()
        {
            stateMachine.ReusableData.MovementInput = stateMachine.Player.PlayerInput.PlayerActions.Movement.ReadValue<Vector2>();
        }

        // 添加不同的碰撞进入事件处理
        private void AddCollider2DEnterActions()
        {
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Carry.ToString(), CarryColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Fishing.ToString(), FishingColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Axe.ToString(), AxeColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Dig.ToString(), DigColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Doing.ToString(), DoingColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Watering.ToString(), WateringColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Swimming.ToString(), SwimmingColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Hammering.ToString(), HammeringColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Hurt.ToString(), HurtColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Mining.ToString(), MiningColliderEnter2D);
            _onTriggerActionsEnter2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.DroppedItems.ToString(), DroppedItemsColliderEnter2D);
        }

        // 添加不同的碰撞退出事件处理
        private void AddCollider2DExitActions()
        {
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Carry.ToString(), CarryColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Fishing.ToString(), FishingColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Axe.ToString(), AxeColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Dig.ToString(), DigColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Doing.ToString(), DoingColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Watering.ToString(), WateringColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Swimming.ToString(), SwimmingColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Hammering.ToString(), HammeringColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Hurt.ToString(), HurtColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Mining.ToString(), MiningColliderExit2D);
            _onTriggerActionsExit2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.DroppedItems.ToString(), DroppedItemsColliderExit2D);
        }

        //碰撞中
        private void AddTriggerCollider2DStayActions()
        {
            _onTriggerActionsTriggerStay2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Axe.ToString(), AxeColliderStay2D);
            _onTriggerActionsTriggerStay2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Dig.ToString(), DigColliderStay2D);
            _onTriggerActionsTriggerStay2DCallbacks.Add(PlayerStateReusableData.Collider2DTagEnum.Doing.ToString(), DoingColliderStay2D);
        }

        private void AddCollision2DEnterActions()
        {
        }
        private void AddCollision2DExitActions()
        {
        }

        #endregion


        #region 不同的物理碰撞事件处理
        // 钓鱼进入碰撞
        protected virtual void FishingColliderEnter2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsFishingState = true;
            //Debug.Log("可以开始 钓鱼了");
        }

        // 钓鱼退出碰撞
        protected virtual void FishingColliderExit2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsFishingState = false;
            //Debug.Log("退出钓鱼");
        }

        // 搬运进入碰撞
        protected virtual void CarryColliderEnter2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsCarryState = true;
        }
        // 搬运退出碰撞
        protected virtual void CarryColliderExit2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsCarryState = false;
        }

        // 砍树进入碰撞
        protected virtual void AxeColliderEnter2D(Collider2D collider)
        {
            SetInteractNode(collider.gameObject);
            stateMachine.ReusableData.IsAxeingState = true;
            // if (stateMachine.ReusableData.PlayerStatesData.PlayerAxeData.AxeTreeNode != null)
            // {
            //     if (stateMachine.ReusableData.PlayerStatesData.PlayerAxeData.AxeTreeNode.TryGetComponent<GameObjHighLight>(out GameObjHighLight treeGameObjHighLight)) treeGameObjHighLight.CloseHighLight();
            // }
            //存储砍树节点
            stateMachine.ReusableData.PlayerStatesData.PlayerAxeData.AxeTreeNode = collider.gameObject;
            // if (collider.TryGetComponent<GameObjHighLight>(out GameObjHighLight gameObjHighLight))
            // {
            //     //gameObjHighLight.CloseHighLight();
            //     gameObjHighLight.OpenHighLight();
            // }
        }
        // 砍树碰撞中
        protected virtual void AxeColliderStay2D(Collider2D collider)
        {
            if (stateMachine.ReusableData.CollisionNode == null) SetInteractNode(collider.gameObject);
            //
            if (stateMachine.ReusableData.PlayerStatesData.PlayerAxeData.AxeTreeNode == null)
            {
                stateMachine.ReusableData.IsAxeingState = true;
                stateMachine.ReusableData.PlayerStatesData.PlayerAxeData.AxeTreeNode = collider.gameObject;
                // if (collider.TryGetComponent<GameObjHighLight>(out GameObjHighLight gameObjHighLight))
                // {
                //     //gameObjHighLight.CloseHighLight();
                //     gameObjHighLight.OpenHighLight();
                // }
            }
        }
        // 砍树退出碰撞
        protected virtual void AxeColliderExit2D(Collider2D collider)
        {
            SetInteractNode(null);
            stateMachine.ReusableData.IsAxeingState = false;
            // if (collider.TryGetComponent<GameObjHighLight>(out GameObjHighLight gameObjHighLight))
            // {
            //     gameObjHighLight.CloseHighLight();
            // }
            stateMachine.ReusableData.PlayerStatesData.PlayerAxeData.AxeTreeNode = null;
        }

        // 挖掘进入碰撞
        protected virtual void DigColliderEnter2D(Collider2D collider)
        {
            SetInteractNode(collider.gameObject);
            stateMachine.ReusableData.IsDiggingState = true;
            //存储挖掘节点
            stateMachine.ReusableData.PlayerStatesData.PlayerDigData.digSoilNode = collider.gameObject;
        }
        // 挖掘中碰撞
        protected virtual void DigColliderStay2D(Collider2D collider)
        {
            if (stateMachine.ReusableData.CollisionNode == null) SetInteractNode(collider.gameObject);
            if (stateMachine.ReusableData.PlayerStatesData.PlayerDigData.digSoilNode == null)
            {
                stateMachine.ReusableData.IsDiggingState = true;
                stateMachine.ReusableData.PlayerStatesData.PlayerDigData.digSoilNode = collider.gameObject;
            }
        }
        // 挖掘退出碰撞
        protected virtual void DigColliderExit2D(Collider2D collider)
        {
            SetInteractNode(null);
            stateMachine.ReusableData.IsDiggingState = false;
            stateMachine.ReusableData.PlayerStatesData.PlayerDigData.digSoilNode = null;
        }

        // 采集/工作碰撞
        protected virtual void DoingColliderEnter2D(Collider2D collider)
        {
            SetInteractNode(collider.gameObject);
            stateMachine.ReusableData.IsDoingState = true;
            stateMachine.ReusableData.PlayerStatesData.PlayerDoingData.doingNode = collider.gameObject;
        }
        // 采集/工作中碰撞
        protected virtual void DoingColliderStay2D(Collider2D collider)
        {
            if (stateMachine.ReusableData.CollisionNode == null) SetInteractNode(collider.gameObject);
            if (stateMachine.ReusableData.PlayerStatesData.PlayerDoingData.doingNode == null)
            {
                stateMachine.ReusableData.IsDoingState = true;
                stateMachine.ReusableData.PlayerStatesData.PlayerDoingData.doingNode = collider.gameObject;
            }
        }
        // 采集/工作退出碰撞
        protected virtual void DoingColliderExit2D(Collider2D collider)
        {
            SetInteractNode(null);
            stateMachine.ReusableData.IsDoingState = false;
            stateMachine.ReusableData.PlayerStatesData.PlayerDoingData.doingNode = null;
        }

        //浇水进入碰撞
        protected virtual void WateringColliderEnter2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsWateringState = true;
        }
        //浇水退出碰撞
        protected virtual void WateringColliderExit2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsWateringState = false;
        }

        //游泳进入碰撞
        protected virtual void SwimmingColliderEnter2D(Collider2D collider)
        {
            //stateMachine.ReusableData.IsSwimmingState = true;
            stateMachine.ChangeState(stateMachine.SwimmingState);
        }
        //游泳退出碰撞
        protected virtual void SwimmingColliderExit2D(Collider2D collider)
        {
        }

        //建造进入碰撞
        protected virtual void HammeringColliderEnter2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsHammeringState = true;
        }
        //建造退出碰撞
        protected virtual void HammeringColliderExit2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsHammeringState = false;
        }

        // 受击进入碰撞
        protected virtual void HurtColliderEnter2D(Collider2D collider)
        {
            // 计算从角色到最接近点的向量
            Vector2 toClosestPoint = (Vector2)stateMachine.Player.transform.position - (Vector2)collider.transform.position;
            stateMachine.ReusableData.PlayerStatesData.PlayerHurtData.HurtSourceNormal = toClosestPoint.normalized;
            //
            stateMachine.ChangeState(stateMachine.HurtState);
        }
        // 受击退出碰撞
        protected virtual void HurtColliderExit2D(Collider2D collider)
        {
        }

        // 采矿进入碰撞
        protected virtual void MiningColliderEnter2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsMiningState = true;
        }
        // 采矿退出碰撞
        protected virtual void MiningColliderExit2D(Collider2D collider)
        {
            stateMachine.ReusableData.IsMiningState = false;
        }
        // 凋落物碰撞
        protected virtual void DroppedItemsColliderEnter2D(Collider2D collider)
        {
            //拾取
            DroppedItemsBase droppedItemsBase = collider.gameObject.GetComponent<DroppedItemsBase>();

            if (droppedItemsBase.IsPickup())
            {
                //拾取
                droppedItemsBase.DestroyDroppedItems();
                //掉落物品类型
                GameObjEnumClass.DroppedItemsEnum droppedItemsType = droppedItemsBase.GetDroppedItemsType();
                //增加背包物品 TODO
            }
        }
        protected virtual void DroppedItemsColliderExit2D(Collider2D collider)
        {
        }

        #endregion



        #region 只允许子类调用的方法

        // 获取朝向
        protected PlayerSO.PlayerFaceEnum GetFaceDirection(Vector2 direction)
        {
            if (direction.x == 0) return stateMachine.ReusableData.playerFaceEnum;
            return direction.x > 0 ? PlayerSO.PlayerFaceEnum.Right : PlayerSO.PlayerFaceEnum.Left;
        }

        //根据传来的节点 更改角色朝向
        protected void ChangeFaceDirection(GameObject nodeObj)
        {
            if (nodeObj == null) return;
            PlayerSO.PlayerFaceEnum playerFace = stateMachine.Player.GetPlayerFace();
            Vector3 normal = nodeObj.transform.position - stateMachine.Player.transform.position;
            PlayerSO.PlayerFaceEnum playerFaceEnum = GetFaceDirection(normal);
            if (playerFaceEnum != playerFace)
            {
                stateMachine.Player.SetPlayerFace(playerFaceEnum);
            }
        }

        //根据朝向返回 向量
        protected Vector2 GetDirectionToVector2(PlayerSO.PlayerFaceEnum playerFaceEnum)
        {
            return playerFaceEnum == PlayerSO.PlayerFaceEnum.Right ? Vector2.right : Vector2.left;
        }

        // 播放动画
        protected void StartAnimation(int animationHash)
        {
            stateMachine.Player.StartAnimation(animationHash);
        }
        // 停止动画
        protected void StopAnimation(int animationHash)
        {
            stateMachine.Player.StopAnimation(animationHash);
        }

        //获取速度
        protected float GetMovementSpeed()
        {
            return movementData.BaseSpeed * stateMachine.ReusableData.MovementSpeedModifier;
        }

        // 角色是否正在移动
        protected bool IsMoving()
        {
            return stateMachine.ReusableData.IsMove;
        }

        //赋值交互节点
        protected void SetInteractNode(GameObject interactNode)
        {
            if (interactNode == null || interactNode.TryGetComponent(out InteractiveBase interactiveBase))
            {
                stateMachine.ReusableData.CollisionNode = interactNode;
            }
        }

        #endregion


        #region 可被重写方法
        // 添加输入事件
        protected virtual void AddInputActionsCallbacks()
        {
            // 移动
            stateMachine.Player.PlayerInput.PlayerActions.Movement.performed += OnMovementPerformed;
            stateMachine.Player.PlayerInput.PlayerActions.Movement.canceled += OnMovementCanceled;
            stateMachine.Player.PlayerInput.PlayerActions.Movement.started += OnMovementStarted;
            // 交互
            stateMachine.Player.PlayerInput.PlayerActions.Interact.started += OnInteractStarted;
            // 跳
            stateMachine.Player.PlayerInput.PlayerActions.Jump.started += OnJumpStarted;
            // 翻滚
            stateMachine.Player.PlayerInput.PlayerActions.Roll.started += OnRollStarted;
            // 加速
            stateMachine.Player.PlayerInput.PlayerActions.Accelerate.started += OnAccelerateStarted;
            // 攻击
            stateMachine.Player.PlayerInput.PlayerActions.Attack.started += OnAttackStarted;
        }

        // 移除输入事件
        protected virtual void RemoveInputActionsCallbacks()
        {
            // 移动
            stateMachine.Player.PlayerInput.PlayerActions.Movement.performed -= OnMovementPerformed;
            stateMachine.Player.PlayerInput.PlayerActions.Movement.canceled -= OnMovementCanceled;
            stateMachine.Player.PlayerInput.PlayerActions.Movement.started -= OnMovementStarted;
            // 交互
            stateMachine.Player.PlayerInput.PlayerActions.Interact.started -= OnInteractStarted;
            // 跳
            stateMachine.Player.PlayerInput.PlayerActions.Jump.started -= OnJumpStarted;
            // 翻滚
            stateMachine.Player.PlayerInput.PlayerActions.Roll.started -= OnRollStarted;
            // 加速
            stateMachine.Player.PlayerInput.PlayerActions.Accelerate.started -= OnAccelerateStarted;
            // 攻击
            stateMachine.Player.PlayerInput.PlayerActions.Attack.started -= OnAttackStarted;
        }

        #endregion


        #region 输入回调
        // 移动执行回调
        protected virtual void OnMovementPerformed(InputAction.CallbackContext context)
        {
            //
        }
        // 移动取消回调
        protected virtual void OnMovementCanceled(InputAction.CallbackContext context)
        {
            //
            stateMachine.ReusableData.IsMove = false;
        }
        // 移动开始回调
        protected virtual void OnMovementStarted(InputAction.CallbackContext context)
        {
            //
            stateMachine.ReusableData.IsMove = true;
        }

        // 互动执行回调
        protected virtual void OnInteractStarted(InputAction.CallbackContext context)
        {
            //
        }

        // 跳跃执行回调
        protected virtual void OnJumpStarted(InputAction.CallbackContext context)
        {
            //
        }

        // 翻滚执行回调
        protected virtual void OnRollStarted(InputAction.CallbackContext context)
        {
            //
        }

        // 加速执行回调
        protected virtual void OnAccelerateStarted(InputAction.CallbackContext context)
        {
            //
        }

        // 攻击执行回调
        protected virtual void OnAttackStarted(InputAction.CallbackContext context)
        {
            //
        }
        #endregion


    }
}
